package pracamagisterska;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

public class ModalityInternalFrame extends JInternalFrame {

    protected JDesktopPane desktopPane;
    protected JComponent parent;
    protected ModalityInternalFrame childFrame;
    protected JComponent focusOwner;
    private boolean wasCloseable;

    public ModalityInternalFrame() {
        init(); // here to allow netbeans to use class in gui builder
    }

    public ModalityInternalFrame(JComponent parent, DatabaseThread db) { //Review
        this(parent, db, null);
    }

    public ModalityInternalFrame(JComponent parent, DatabaseThread db, String[] list) {
        this(parent, db, list, null);
    }

    public ModalityInternalFrame(JComponent parent, String text) { //Warning + error
        this(parent, text, null);
    }

    public ModalityInternalFrame(JComponent parent, String text, DatabaseThread db) { //Warning PersonDetails Change
        this(parent, text, db, false);
    }

    public ModalityInternalFrame(JComponent parent, DatabaseThread db, String[] list, ArrayList<String> settings) { //Config
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    public ModalityInternalFrame(JComponent parent, BufferedImage img) { //Image crop
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    public ModalityInternalFrame(JComponent parent, ReviewList item, DatabaseThread db, boolean x) { //PersonDetails / Card
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    public ModalityInternalFrame(JComponent parent, ReviewList item, DatabaseThread db, int x) { // Card
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    public ModalityInternalFrame(JComponent parent, String text, DatabaseThread db, boolean x) { //PersonReview-details
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    public ModalityInternalFrame(JComponent parent, ArrayList<ReviewList> l, String karta, DatabaseThread db) { //PrintFrame
        setParentFrame(parent);
        setFocusTraversalKeysEnabled(false);
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).setChildFrame(ModalityInternalFrame.this);
        }
        GlassPane glassPane = new GlassPane(this);
        setGlassPane(glassPane);
        addFrameListener();
        init();
    }

    private void setParentFrame(JComponent parent) {
        desktopPane = JOptionPane.getDesktopPaneForComponent(parent);
        this.parent = parent == null ? JOptionPane.getDesktopPaneForComponent(parent) : parent; // default to desktop if no parent given
    }

    public JComponent getParentFrame() {
        return parent;
    }

    public void setChildFrame(ModalityInternalFrame childFrame) {
        this.childFrame = childFrame;
    }

    public ModalityInternalFrame getChildFrame() {
        return childFrame;
    }

    public boolean hasChildFrame() {
        return (childFrame != null);
    }

    protected void addFrameListener() {
        addInternalFrameListener(new InternalFrameAdapter() {
            @Override
            public void internalFrameActivated(InternalFrameEvent e) {
                if (hasChildFrame() == true) {
                    getGlassPane().setVisible(true);
                    grabFocus();
                } else {
                    getGlassPane().setVisible(false);
                }
            }

            @Override
            public void internalFrameDeactivated(InternalFrameEvent e) {
                if (hasChildFrame() == true) {
                    getGlassPane().setVisible(true);
                    grabFocus();
                } else {
                    getGlassPane().setVisible(false);
                }
            }

            @Override
            public void internalFrameOpened(InternalFrameEvent e) {
                getGlassPane().setVisible(false);
            }

            @Override
            public void internalFrameClosing(InternalFrameEvent e) {
                if (parent != null && parent instanceof ModalityInternalFrame) {
                    ((ModalityInternalFrame) parent).childClosing();
                }
            }
        });
    }

    protected void childClosing() {
        setClosable(wasCloseable);
        getGlassPane().setVisible(false);
        if (focusOwner != null) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        moveToFront();
                        setSelected(true);
                        focusOwner.grabFocus();
                    } catch (PropertyVetoException ex) {
                        Logger.getLogger(ModalityInternalFrame.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            focusOwner.grabFocus();
        }
        getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        setChildFrame(null);
    }

    protected void childOpening() {
        setClosable(false);
        focusOwner = (JComponent) getFocusOwner();
        grabFocus();
        getGlassPane().setVisible(true);
        getGlassPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    }

    @Override
    public void show() {
        if (parent != null && parent instanceof ModalityInternalFrame) {
            ((ModalityInternalFrame) parent).childOpening();
        }
        calculateBounds();
        super.show();
    }

    protected void init() {
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 394, Short.MAX_VALUE));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 274, Short.MAX_VALUE));

        pack();
    }

    public void calculateBounds() {
        Dimension frameSize = getPreferredSize();
        Dimension parentSize = new Dimension();
        Dimension rootSize = new Dimension(); // size of desktop
        Point frameCoord = new Point();

        if (desktopPane != null) {
            rootSize = desktopPane.getSize(); // size of desktop
            frameCoord = SwingUtilities.convertPoint(parent, 0, 0, desktopPane);
            parentSize = parent.getSize();
        }

        int x = (parentSize.width - frameSize.width) / 2 + frameCoord.x;
        int y = (parentSize.height - frameSize.height) / 2 + frameCoord.y;

        int ovrx = x + frameSize.width - rootSize.width;
        int ovry = y + frameSize.height - rootSize.height;
        x = Math.max((ovrx > 0 ? x - ovrx : x), 0);
        y = Math.max((ovry > 0 ? y - ovry : y), 0);
        setBounds(x, y, frameSize.width, frameSize.height);
    }
}
